package com.ruoyi.web.service.impl;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.live.model.v20161101.*;
import com.aliyuncs.profile.DefaultProfile;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ExceptionUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * description:
 * auth fcb
 * date 2025-07-16 10:06
 **/
@Service
@Slf4j
public class AliyunLiveService {

    @Value("${aliyun.regionId}")
    private String regionId;

    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;


    /**
     * 查询域名在线流列表
     * 文档：<a href="https://help.aliyun.com/zh/live/developer-reference/api-live-2016-11-01-describelivestreamsonlinelist">查询域名在线流列表</a>
     * @param request
     * @return
     */
    public DescribeLiveStreamsOnlineListResponse describeLiveStreamsOnlineList(DescribeLiveStreamsOnlineListRequest request) {
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        DescribeLiveStreamsOnlineListResponse response = null;
        try {
            response = client.getAcsResponse(request);
            return response;
        }catch (Exception e) {
            log.error("【调用阿里云直播API(查询域名在线流列表)异常】：{}", ExceptionUtil.getExceptionMessage(e));
            return null;
        }
    }

    /**
     * 查询单路流状态
     * 文档：<a href="https://help.aliyun.com/zh/live/developer-reference/api-live-2016-11-01-describelivestreamstate">查询单路流状态</a>
     * @param request
     * @return
     */
    public DescribeLiveStreamStateResponse describeLiveStreamState(DescribeLiveStreamStateRequest request) {
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        DescribeLiveStreamStateResponse response = null;
        try {
            response = client.getAcsResponse(request);
            return response;
        }catch (Exception e) {
            log.error("【调用阿里云直播API(查询单路流状态)异常】：{}", ExceptionUtil.getExceptionMessage(e));
            return null;
        }
    }

    /**
     * 生成鉴权URL
     * 文档：<a href="https://help.aliyun.com/zh/live/user-guide/ingest-and-streaming-urls">生成推流地址和播放地址</a>
     * @param appName 阿里云控制台配置的appName
     * @param streamName 阿里云控制台配置的streamName
     * @param videoType 视频格式，目前仅支持flv和m3u8
     * @param expireTime 视频时长，单位：秒
     * @return 鉴权后的URL，例如：http://dx1test-play.shinmade.com/AppName/StreamName.m3u8?auth_key=1752655498-0-0-b840bf448f1ba6b3bf1bdd99250ea268
     */
    public String getAuthUrl(String domain, String appName, String streamName, String videoType, Long expireTime) {
        String key = getAuthKey(domain);
        if(StringUtils.isEmpty( key)) {
            throw new ServiceException("请求鉴权key失败");
        }
        if(!"flv".equalsIgnoreCase(videoType) && !"m3u8".equalsIgnoreCase(videoType)) {
            throw new ServiceException("暂不支持视频格式或协议：" + videoType);
        }
        String uri = "/" + appName + "/" + streamName + "." + videoType;
        String rand = "0";  // "0" by default, other value is ok
        String uid = "0";   // "0" by default, other value is ok
        long exp = (System.currentTimeMillis() / 1000) + expireTime;
        String sString = String.format("%s-%s-%s-%s-%s", uri, exp, rand, uid, key);
        String hashValue = md5Sum(sString);
        String authKey = String.format("%s-%s-%s-%s", exp, rand, uid, hashValue);
        return "https://" + domain + uri + "?auth_key=" + authKey;
    }

    /**
     * 获取阿里云鉴权key
     * @return
     */
    private String getAuthKey(String domain) {
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        DescribeLiveDomainConfigsRequest describeLiveDomainConfigsRequest=new DescribeLiveDomainConfigsRequest();
        describeLiveDomainConfigsRequest.setDomainName(domain);
        describeLiveDomainConfigsRequest.setFunctionNames("aliauth");
        DescribeLiveDomainConfigsResponse describeLiveStreamSnapshotInfoResponse = null;
        try {
            describeLiveStreamSnapshotInfoResponse = client.getAcsResponse(describeLiveDomainConfigsRequest);
        }catch (Exception e) {
            log.error("【调用阿里云直播API(获取阿里云鉴权key)异常】：{}", ExceptionUtil.getExceptionMessage(e));
            return "";
        }
        //鉴权key
        String key = "";
        for(DescribeLiveDomainConfigsResponse.DomainConfig.FunctionArg f:describeLiveStreamSnapshotInfoResponse.getDomainConfigs().get(0).getFunctionArgs()){
            if("auth_key1".equals(f.getArgName())){
                key = f.getArgValue();
            }
        }
        return key;
    }

    private static String md5Sum(String src) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        md5.update(StandardCharsets.UTF_8.encode(src));
        return String.format("%032x", new BigInteger(1, md5.digest()));
    }

}
